package com.basker.pisces.domain.command.option;

import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

import org.springframework.util.CollectionUtils;

import com.basker.pisces.domain.command.meta.Command;
import com.basker.pisces.domain.command.run.ICommandExecuteDataObjectHandler;

/**
 * 命令执行选项，在命令执行时由外部传入，可以在执行过程中做一些允许范围内的控制
 *
 * @author hangwen
 */
public class CommandExecuteOption {

    /**
     * 全局默认选项，不可更改
     */
    public static final CommandExecuteOption DEFAULT_OPTION = new CommandExecuteOption() {
        @Override
        public void addParameter(String key, Object value) {

        }

        @Override
        public void setDataObjectHandler(ICommandExecuteDataObjectHandler dataObjectHandler) {

        }

        @Override
        public void setDisableEvent(boolean disableEvent) {

        }

        @Override
        public void setDisableLock(boolean disableLock) {

        }

        @Override
        public void setThrowExceptionWhileValidationFailInTransationScope(
                boolean throwExceptionWhileValidationFailInTransationScope) {
        }
    };

    private ICommandExecuteDataObjectHandler dataObjectHandler;
    private Set<String> disableValidations;
    private boolean throwExceptionWhileValidationFailInTransationScope = true;
    private boolean disableLock = false;
    private boolean disableEvent = false;

    private Map<String, Object> parameters;

    public CommandExecuteOption() {

    }

    /**
     * 添加禁用的校验器
     *
     * @param validationName
     */
    public void addDisableValidation(String validationName) {
        if (this.disableValidations == null) {
            this.disableValidations = new LinkedHashSet<>();
        }

        this.disableValidations.add(validationName);
    }

    /**
     * 添加参数
     *
     * @param key
     * @param value
     */
    public void addParameter(String key, Object value) {
        if (this.parameters == null) {
            this.parameters = new HashMap<>();
        }

        this.parameters.put(key, value);
    }

    /**
     * 获取数据对象处理器
     *
     * @return
     */
    public ICommandExecuteDataObjectHandler getDataObjectHandler() {
        return dataObjectHandler;
    }

    /**
     * 获取指定参数
     *
     * @param key
     * @return
     */
    public Object getParamter(String key) {
        return this.parameters != null ? this.parameters.get(key) : null;
    }

    /**
     * 是否禁止发布事件
     *
     * @return
     */
    public boolean isDisableEvent() {
        return disableEvent;
    }

    /**
     * 是否强制禁用锁，对{@link Command#getEnableLock()}的命令有效
     *
     * @return
     */
    public boolean isDisableLock() {
        return disableLock;
    }

    /**
     * 在事务内执行校验、并且校验失败，是否抛出异常，默认true
     *
     * @return
     */
    public boolean isThrowExceptionWhileValidationFailInTransationScope() {
        return throwExceptionWhileValidationFailInTransationScope;
    }

    /**
     * 指定验证器是否被禁用
     *
     * @param validationName
     * @return
     */
    public boolean isValidationDisable(String validationName) {
        return CollectionUtils.isEmpty(disableValidations) ? false : disableValidations.contains(validationName);
    }

    public void setDataObjectHandler(ICommandExecuteDataObjectHandler dataObjectHandler) {
        this.dataObjectHandler = dataObjectHandler;
    }

    public void setDisableEvent(boolean disableEvent) {
        this.disableEvent = disableEvent;
    }

    public void setDisableLock(boolean disableLock) {
        this.disableLock = disableLock;
    }

    public void setThrowExceptionWhileValidationFailInTransationScope(
            boolean throwExceptionWhileValidationFailInTransationScope) {
        this.throwExceptionWhileValidationFailInTransationScope = throwExceptionWhileValidationFailInTransationScope;
    }

}
